<template>
    <h1>查看成绩</h1>
    <div class="search-div">
        <el-row :gutter="24" class="course-info-container">
            <el-col :span="12">
                <el-row class="course-info-container-left">
                    <el-col :span="9">
                        <el-row>
                            <el-col :span="8"><strong>开课学院：</strong></el-col>
                            <el-col :span="16">{{ course.collegeName }}</el-col>
                        </el-row>
                    </el-col>
                    <el-col :span="9">
                        <el-row>
                            <el-col :span="8"><strong>任课教师：</strong></el-col>
                            <el-col :span="16">{{ course.teacherName }}</el-col>
                        </el-row>
                    </el-col>
                    <el-col :span="6">
                        <el-row>
                            <el-col :span="8"><strong>学分：</strong></el-col>
                            <el-col :span="16">{{ course.credits }}</el-col>
                        </el-row>
                    </el-col>
                    <el-col :span="9">
                        <el-row>
                            <el-col :span="8"><strong>课程代码：</strong></el-col>
                            <el-col :span="16">{{ course.code }}</el-col>
                        </el-row>
                    </el-col>
                    <el-col :span="9">
                        <el-row>
                            <el-col :span="8"><strong>课程名称：</strong></el-col>
                            <el-col :span="16">{{ course.name }}</el-col>
                        </el-row>
                    </el-col>
                    <el-col :span="6">
                        <el-row>
                            <el-col :span="10"><strong>总学时：</strong></el-col>
                            <el-col :span="10">{{ course.period }}</el-col>
                        </el-row>
                    </el-col>
                </el-row>
            </el-col>
            <el-col :span="12">
                <el-form :model="queryDto">
                    <el-row>
                        <el-col :span="12">
                            <el-form-item label="学年">
                                <el-select v-model="queryDto.academicYear" @change="findClassesList"
                                           placeholder="请选择学年">
                                    <el-option v-for="year in academicYearList" :key="year" :label="academicYears[year]"
                                               :value="year"/>
                                </el-select>
                            </el-form-item>
                        </el-col>
                        <el-col :span="12">
                            <el-form-item label="学期">
                                <el-select v-model="queryDto.semester" placeholder="请选择学期"
                                           @change="findClassesList">
                                    <el-option v-for="(label,value) in semesters" :key="value" :label="label"
                                               :value="value"/>
                                </el-select>
                            </el-form-item>
                        </el-col>
                        <el-col :span="12">
                            <el-form-item label="教学班" style="font-weight: bold;">
                                <el-select v-model="queryDto.teachingClassId" placeholder="请选择" clearable="true">
                                    <el-option v-for="item in teachingClassList" :key="item.id" :label="item.name"
                                               :value="item.id"/>
                                </el-select>
                            </el-form-item>
                        </el-col>
                        <el-col :span="12">
                            <el-form-item>
                                <el-row :gutter="24">
                                    <el-col :span="6">
                                        <el-button type="primary" size="small" @click="search">搜索</el-button>
                                    </el-col>
                                    <el-col :span="6">
                                        <el-button type="info" size="small" @click="resetDate">重置</el-button>
                                    </el-col>
                                    <el-col :span="6">
                                        <el-upload class="upload-demo" :before-upload="beforeUpload"
                                                   :action="`http://localhost:8501/admin/educational/recordScore/importData?teachingClassId=${queryDto.teachingClassId}`"
                                                   :on-success="onUploadSuccess" :limit="1" :headers="headers">
                                            <el-button size="small" type="primary">导入</el-button>
                                        </el-upload>
                                    </el-col>
                                    <el-col :span="6">
                                        <el-button type="success" size="small" @click="exportExcel">导出</el-button>
                                    </el-col>
                                </el-row>
                            </el-form-item>
                        </el-col>
                    </el-row>
                </el-form>
            </el-col>
        </el-row>
    </div>
    <el-tag type="success">
        <i class="el-icon-s-data"/>
        <span>        成绩计算规则：
            <template v-for="(item, index) in gradeItems" :key="index">
                {{ item.gradeComponentName }}占{{ item.weightage * 100 }}%
                <span v-if="index !== gradeItems.length - 1">、</span>
            </template>
        </span>
    </el-tag>

  <!-- 弹窗组件 -->
    <el-dialog v-model="dialogVisible" title="录入学生成绩" draggable width="30%"
               @close="handleDialogVisibleClose">
        <el-form label-width="80px">
            <el-form-item label="课程名称">
                <el-input v-model="detailForm.courseName" disabled/>
            </el-form-item>
            <el-form-item label="学生姓名">
                <el-input v-model="detailForm.studentName" disabled/>
            </el-form-item>
            <el-form-item label="学生学号">
                <el-input v-model="detailForm.studentNumber" disabled/>
            </el-form-item>
            <el-form-item v-for="detail in detailForm.gradeDetailVoList" :key="detail.gradeComponentCourseId"
                          :label="detail.gradeComponentItemName">
                <el-input-number v-model="detail.score" :precision="2" :step="0.1" :max="100"/>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="submit">保存</el-button>
                <el-button @click="dialogVisible = false">取消</el-button>
                <el-button type="warning" @click="calculateTotalScore">计算总成绩</el-button>
            </el-form-item>
        </el-form>
    </el-dialog>

    <div class="table-container">
        <el-table :data="list" style="width: 100%">
            <el-table-column prop="studentNumber" label="学号"/>
            <el-table-column prop="studentName" label="学生姓名"/>
            <el-table-column prop="courseName" label="课程名称"/>
            <el-table-column prop="academicYear" #default="scope" label="学年">
                {{ academicYears[scope.row.academicYear] }}
            </el-table-column>
            <el-table-column prop="semester" #default="scope" label="学期">
                {{ semesters[scope.row.semester] }}
            </el-table-column>
            <!-- 渲染成绩详细列表 -->
            <el-table-column v-for="(item, index) in gradeItems" :key="index" #default="scope"
                             :label="item.gradeComponentName">
                <div v-for="(detail, index) in scope.row.gradeDetailVoList" :key="index">
                    <p v-if="detail.gradeComponentItemName === item.gradeComponentName">{{ detail.score }}</p>
                </div>
            </el-table-column>
            <el-table-column prop="totalScore" label="总成绩" #default="scope">
                <p :style="{ color: scope.row.totalScore > 60 ? 'green' : 'red' }">{{ scope.row.totalScore }}</p>
            </el-table-column>
            <el-table-column prop="isMakeupExam" label="是否需要补考" #default="scope">
                <div v-if="scope.row.totalScore !==null ">
                    <el-tag v-if="scope.row.isMakeupExam === 1" type="success">是</el-tag>
                    <el-tag v-else type="danger">否</el-tag>
                </div>
            </el-table-column>
            <el-table-column prop="totalScore" #default="scope" label="等级">
                <div v-if="scope.row.totalScore!==null">
                    <el-tag v-if="scope.row.totalScore >=90 && scope.row.totalScore <= 100" type="success">优</el-tag>
                    <el-tag v-else-if="scope.row.totalScore >=80 && scope.row.totalScore < 90" type="warning">良
                    </el-tag>
                    <el-tag v-else-if="scope.row.totalScore >=70 && scope.row.totalScore < 80" type="info">中</el-tag>
                    <el-tag v-else-if="scope.row.totalScore >=60 && scope.row.totalScore < 70" type="warning">及格
                    </el-tag>
                    <el-tag v-else-if="scope.row.totalScore <60" type="danger">不及格</el-tag>
                </div>
            </el-table-column>
            <el-table-column label="操作" #default="scope">
                <el-button type="text" @click="showDetail(scope.row)">查看详情</el-button>
            </el-table-column>
        </el-table>
        <el-pagination v-model:current-page="pageParams.page" v-model:page-size="pageParams.limit"
                       :page-sizes="[5, 10, 20, 50, 100]" @size-change="fetchData" @current-change="fetchData"
                       layout="total, sizes, prev, pager, next" :total="total"/>
    </div>
</template>

<script setup>
import {onMounted, ref} from 'vue';
import router from "@/router";
import {
    FindAllTeachingClassByCourseIdAndTeacherId,
    FindGradeInfoByPage,
    SaveGradeDetailInfo,
    UpdateTotalScore
} from "@/api/recordScore";
import {GetGradeComponentIds} from "@/api/course";
import {ElMessage} from "element-plus";
import {useApp} from "@/pinia/modules/app";

const academicYearList = [2024, 2023, 2022, 2021, 2020, 2019];
const academicYears = {
    2024: "2024-2025",
    2023: "2023-2024",
    2022: "2022-2023",
    2021: "2021-2022",
    2020: "2020-2021",
    2019: "2019-2020"
};
const semesters = {1: '第一学期', 2: '第二学期'}// 学期选项列表
const teachingClassList = ref({}) // 班级选项列表，需从后端获取
const course = ref({});
const gradeItems = ref([])

const queryDto = ref({
    academicYear: null,
    semester: null,
    teachingClassId: null
})
const headers = {
    token: useApp().authorization.token, // 从pinia中获取token，在进行文件上传的时候将token设置到请求头中
}
const beforeUpload = (file) => {
    if (queryDto.value.academicYear != null && queryDto.value.semester != null && queryDto.value.teachingClassId != null) {
        // 验证文件类型
        const fileType = file.type
        const fileTypes = ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel']
        if (!fileTypes.includes(fileType)) {
            ElMessage.error('请上传正确的文件格式')
            return false
        }
        // 验证文件大小
        const fileSize = file.size
        const maxSize = 2 * 1024 * 1024
        if (fileSize > maxSize) {
            ElMessage.error('文件大小不能超过2M')
            return false
        }
        if (queryDto.value.teachingClassId === null) {
            ElMessage.error('请先选择教学班级')
            return false
        }
        return true
    } else {
        ElMessage.error('请先选择教学班级')
        return false
    }
}
//导入成功
const onUploadSuccess = async (response, file) => {
    if (response.code === 200) {
        ElMessage.success('导入成功')
        await fetchData()
    } else {
        ElMessage.error('导入失败')
    }
}
//导出
const exportExcel = async () => {
    if (queryDto.value.academicYear != null && queryDto.value.semester != null && queryDto.value.teachingClassId != null) {
        console.log(JSON.stringify(queryDto.value))
        try {
            // 发送请求到后端下载模板
            const response = await fetch(`http://localhost:8501/admin/educational/recordScore/downloadTemplate`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    token: useApp().authorization.token
                },
                body: JSON.stringify(queryDto.value)
            });
            // 将文件内容转换为 Blob 对象
            const blob = await response.blob();
            // 创建隐藏的 <a> 标签
            const link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            // 设置文件名并触发下载
            link.download = `${queryDto.value.academicYear}年 第${queryDto.value.semester}学期${teachingClassList.value.find(item => item.id === queryDto.value.teachingClassId)?.name}学生成绩表.xlsx`;
            // 设置默认文件名
            document.body.appendChild(link);
            link.click();
            // 清理
            document.body.removeChild(link);
        } catch (error) {
            console.error('下载模板失败', error);
            ElMessage.error('下载模板失败');
        }
    } else if (queryDto.value.teachingClassId === null) {
        ElMessage.error('请先选择教学班级')
    } else {
        ElMessage.error('请先选择学年和学期')
    }
}

const detailForm = ref({
    id: '',
    studentNumber: '',
    studentName: '',
    courseName: '',
    gradeDetailVoList: {
        id: '',
        gradeComponentCourseId: '',
        gradeComponentItemName: '',
        weightage: '',
        score: ''
    }
})

const dialogVisible = ref(false) // 控制弹窗显示隐藏
const showDetail = async (row) => {
    detailForm.value = row
    dialogVisible.value = true
}
const handleDialogVisibleClose = () => {
    detailForm.value = {}
    dialogVisible.value = false
}
const submit = async () => {
    await saveGradeDetail()
    await fetchData()
}
const calculateTotalScore = async () => {
    let hasInvalidScore = false;
    for (const detail of detailForm.value.gradeDetailVoList) {
        if (!detail.score || detail.score < 0 || detail.score > 100) {
            hasInvalidScore = true;
            break; // 如果有无效分数，立即跳出循环
        }
    }
    if (hasInvalidScore) {
        // 处理无效分数的逻辑
        ElMessage.error('请输入全部成绩');
        return; // 或者抛出一个错误
    }
    const totalScore = detailForm.value.gradeDetailVoList.reduce((acc, cur) => {
        return acc + cur.score * cur.weightage;
    }, 0);
    await saveGradeDetail()
    const {code} = await UpdateTotalScore(detailForm.value.id, totalScore);
    if (code === 200) {
        ElMessage.success('操作成功');
        await fetchData();
        dialogVisible.value = false;
    } else {
        ElMessage.error('操作失败');
    }
}

const saveGradeDetail = async () => {
    const {code} = await SaveGradeDetailInfo(detailForm.value.gradeDetailVoList)
    if (code === 200) {
        ElMessage.success('保存成功')
    } else {
        ElMessage.error('保存失败')
    }
}


// 分页条总记录数
let total = ref(0)
// 定义表格数据模型
let list = ref([]) // 成绩数据，需从后端获取
//分页数据
const pageParamsForm = {
    page: 1, // 页码
    limit: 10, // 每页记录数
}
const pageParams = ref(pageParamsForm) // 将pageParamsForm包装成支持响应式的对象
const fetchData = async () => {
    const {data} = await FindGradeInfoByPage(
        pageParams.value.page,
        pageParams.value.limit,
        queryDto.value.teachingClassId
    )
    list.value = data?.list || [];
    total.value = data?.total || 0;
}

const search = async () => {
    if (queryDto.value.teachingClassId != null && queryDto.value.teachingClassId !== '') {
        await fetchData();
    } else {
        ElMessage.error('请选择班级！');
        return false;
    }
}

onMounted(async () => {
    course.value = router.currentRoute.value.query;
    await findGradeItems();
})

const findClassesList = async () => {
    if (queryDto.value.academicYear != null && queryDto.value.semester != null) {
        const {data} = await FindAllTeachingClassByCourseIdAndTeacherId(router.currentRoute.value.query.id, router.currentRoute.value.query.teacherId, queryDto.value.academicYear, queryDto.value.semester);
        teachingClassList.value = data
    }
}
const findGradeItems = async () => {
    const {data} = await GetGradeComponentIds(course.value.id);
    gradeItems.value = data.map(gradeComponent => {
            return {
                gradeComponentId: gradeComponent.gradeComponentId,
                gradeComponentName: gradeComponent.gradeComponentName,
                weightage: gradeComponent.weightage
            }
        }
    )
}
const resetDate = () => {
    queryDto.value = {}
    list.value = []
    teachingClassList.value = []
}
</script>

<style scoped>

.search-div {
    margin-bottom: 10px;
    border: 1px solid #ebeef5;
    border-radius: 3px;
    background-color: #fff;
}

.course-info-container {
    margin-top: 10px;
    margin-left: 20px;
}

.course-info-container-left {
    height: 100px;
    margin-top: 7px;
    margin-left: 10px;
}

.table-container {
    margin: 10px 0;
    padding: 10px;
    border: 1px solid #ebeef5;
    border-radius: 3px;
    background-color: #fff;
}

</style>
